package com.android.gtravelling;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import com.android.route.*;

import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemLongClickListener;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class MapRouteActivity extends MapActivity{

	ImageButton searchButton;
	ImageButton infoButton;
	EditText inputData;
	LinearLayout searchLayout;
	
	final int ADD_MARKER_ITEM = 0;
	final int ADD_FROM_LOCATION = 1;
	final int ADD_TO_LOCATION = 2;
	final int SATELLITE_VIEW = 3;
	final int TRAFFIC_VIEW = 4;
	final int GET_ADD = 5;
	final int BACK_MAP = 6;
	
	GeoPoint getGeoPoint;
	Geocoder geocoder;
	GeoPoint point;
	GeoPoint startPoint;
	GeoPoint stopPoint;
	
	int countColor = 0;
	int colorLine;
	
	MyItemOverlay myItemOverlay;
	MyItemOverlay myItemSourcePoint;
	MyItemOverlay myItemDestinationPoint;
	
	private int selectContextMenu = 0;
	private int positionAddress;
	
	private List<Address> addresses;
	private ListView resultList;
	
	LinearLayout linearLayout;
	MapView mapView;
	private Road mRoad;
	public MapController mapController;
	private GeoPoint p;
	private String destinationPlace="";
	ConvertUnsigned conv=new ConvertUnsigned();
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mapview);
		mapView = (MapView) findViewById(R.id.myMap);
		mapView.setBuiltInZoomControls(true);
		registerForContextMenu(mapView);
		mapController = mapView.getController();
		
		Bundle extras = getIntent().getExtras();
		String tam=extras.getString(Intent.EXTRA_TEXT);
		destinationPlace=conv.ConvertStringURI(tam);
		System.out.println(destinationPlace);
		
		registerForContextMenu(resultList);
		
		resultList = (ListView) findViewById(R.id.resultList);
		resultList.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int position, long arg3) {
				// TODO Auto-generated method stub
				selectContextMenu = 0;
				positionAddress = position;
				registerForContextMenu(resultList);
				return false;
			}
		});

		
		LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		LocationListener mlocListener = new MyLocationListener();
		mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
				mlocListener);
	}

	private void SearchAction(String searchText){

		String addressLine = "";
		List<String> items = new ArrayList<String>();
		geocoder = new Geocoder(this,
				Locale.getDefault());
		try {
			addresses = geocoder.getFromLocationName(searchText, 10);
			if (addresses.size() > 0) {
				for (int i = 0; i < addresses.size(); i++) {
					for (int j = 0; j <= addresses.get(i)
							.getMaxAddressLineIndex(); j++) {
						addressLine += addresses.get(i).getAddressLine(j)
								+ ",";
					}
					items.add(addressLine);
					addressLine = "";
				}
				setListItems(items);
				resultList.setVisibility(0);
			} else {
				Toast.makeText(getBaseContext(), "Address not found!",
						Toast.LENGTH_LONG).show();
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	private void setListItems(List<String> itemsList) {
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, itemsList);
		resultList.setAdapter(adapter);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		if (selectContextMenu == 0) {
			getGeoPoint = new GeoPoint((int) (addresses.get(positionAddress)
					.getLatitude() * 1E6), (int) (addresses
					.get(positionAddress).getLongitude() * 1E6));
		}

		switch (item.getItemId()) {
		case ADD_MARKER_ITEM:
			mapController.animateTo(getGeoPoint);// nhảy tới điểm đó
			mapController.setZoom(15);// cho zoom in lên 15 lần
			myItemOverlay.addItem(getGeoPoint, "My location", "Add location");
			mapView.getOverlays().add(myItemOverlay);
			resultList.setVisibility(8);
			return true;
		case ADD_FROM_LOCATION:
			startPoint = getGeoPoint;
			mapController.animateTo(getGeoPoint);
			mapController.setZoom(15);
			mapController.animateTo(startPoint);
			myItemSourcePoint.addItem(startPoint, "From here!", "Start point");
			mapView.getOverlays().add(myItemSourcePoint);
			resultList.setVisibility(8);
			return true;
		case ADD_TO_LOCATION:
			setColorLine();
			stopPoint = getGeoPoint;
			mapController.animateTo(getGeoPoint);
			mapController.setZoom(15);
			mapController.animateTo(stopPoint);
			myItemDestinationPoint.addItem(stopPoint, "To here!", "Stop point");
			mapView.getOverlays().add(myItemDestinationPoint);
			//DrawPath(startPoint, stopPoint, mapView);
			
			resultList.setVisibility(8);
			countColor++;
			if (countColor > 2)
				countColor = 0;
			return true;
		case SATELLITE_VIEW:
			mapController.animateTo(getGeoPoint);
			mapController.setZoom(15);
			mapView.setStreetView(false);
			mapView.setTraffic(false);
			mapView.setSatellite(true);
			resultList.setVisibility(8);
			return true;
		case TRAFFIC_VIEW:
			mapController.animateTo(getGeoPoint);
			mapController.setZoom(15);
			// in fact,i shoudn't use setstreetview(true/false) because it's
			// maybe NOT support your location
			mapView.setStreetView(false);
			mapView.setSatellite(false);
			mapView.setTraffic(true);
			resultList.setVisibility(8);
			return true;
		case BACK_MAP:
			return true;
		case GET_ADD:
			GetAddressFromLocation();
			return true;
		default:
			return false;
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		menu.add(0, ADD_MARKER_ITEM, 0, "Mark here");
		menu.add(0, ADD_FROM_LOCATION, 1, "From here");
		if (startPoint != null) {
			menu.add(0, ADD_TO_LOCATION, 2, "To Here");
		}
		menu.add(0, GET_ADD, 3, "Get Address");
		if (mapView.isSatellite())
			menu.add(0, TRAFFIC_VIEW, 4, "Set traffic view here");
		else
			menu.add(0, SATELLITE_VIEW, 4, "Set satellite view here");
		menu.add(0, BACK_MAP, 5, "Back");
		super.onCreateContextMenu(menu, v, menuInfo);
	}
	
	void GetAddressFromLocation() {
		Geocoder geocoder = new Geocoder(getBaseContext(), Locale.getDefault());
		List<String> items = new ArrayList<String>();
		try {
			addresses = geocoder.getFromLocation(
					getGeoPoint.getLatitudeE6() / 1E6,
					getGeoPoint.getLongitudeE6() / 1E6, 5);
			String addressLine = "";
			if (addresses.size() > 0) {
				for (int i = 0; i < addresses.size(); i++) {
					for (int j = 0; j <= addresses.get(i)
							.getMaxAddressLineIndex(); j++) {
						addressLine += addresses.get(i).getAddressLine(j) + ",";
					}
					items.add(addressLine);
					addressLine = "";
				}
				setListItems(items);
				resultList.setVisibility(0);
				infoButton.setVisibility(0);
			} else {
				Toast.makeText(getBaseContext(), "Address not found!",
						Toast.LENGTH_LONG).show();
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	void setColorLine() {
		if (countColor == 0) {
			colorLine = Color.RED;
		} else if (countColor == 1) {
			colorLine = Color.BLUE;
		} else {
			colorLine = Color.GREEN;
		}
	}
	
	public class MyLocationListener implements LocationListener {
		@Override
		public void onLocationChanged(Location loc) {
			loc.getLatitude();
			loc.getLongitude();
			String Text = "My current location is: " + "Latitud = "
					+ loc.getLatitude() + "Longitud = " + loc.getLongitude();
			Toast.makeText(getApplicationContext(), Text, Toast.LENGTH_SHORT)
					.show();
			System.out.println(Text);

			mapView.setTraffic(true);
			mapView.setSatellite(false);
			String coordinates[] = { "" + loc.getLatitude(),
					"" + loc.getLongitude() };// "21.036074", "105.833636" };
			double latiTude = Double.parseDouble(coordinates[0]);
			double longiTude = Double.parseDouble(coordinates[1]);
			p = new GeoPoint((int) (latiTude * 1E6), (int) (longiTude * 1E6));

		/*	 double fromLat=10.71796,fromLon=106.599655;
			    double toLat=10.849154,toLon=106.773376;*/
			    //String sTam=String.valueOf(p.getLatitudeE6())+","+String.valueOf(p.getLongitudeE6());
			    //double fromLat = 49.85, fromLon = 24.016667, toLat = 50.45, toLon = 30.523333;
				/*String url = RoadProvider
						.getUrl(fromLat, fromLon, toLat, toLon);*/
				String sourcePl=String.valueOf(latiTude)+","+String.valueOf(longiTude);//"609,+Lac+Long+Quan,+Ho+Chi+Minh+City,+Viet+nam";
				String destinPl="Suoi+Tien,+Quan+9,+Tp+Ho+Chi+Minh,+Viet+Nam";
				String url1="http://maps.google.com/maps?f=d&hl=en&saddr="+sourcePl+"&daddr="+destinPl+"&ie=UTF8&0&om=0&output=kml";
				//10.849154,106.773376
				//10.71796,106.599655//here
					InputStream is =  getConnection(url1);
					mRoad = RoadProvider.getRoute(is);
				
				mHandler.sendEmptyMessage(0);
			
			
			
			/*mc = mapView.getController();
			mc.animateTo(p);
			mc.setZoom(17);*/
			
			/*MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
			List<Overlay> listOfOverlays = mapView.getOverlays();
			listOfOverlays.clear();
			listOfOverlays.add(mapOverlay);*/
			//mapView.invalidate();
		}

		
		@Override
		public void onProviderDisabled(String provider) {
			Toast.makeText(getApplicationContext(), "Gps Disabled",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onProviderEnabled(String provider) {
			Toast.makeText(getApplicationContext(), "Gps Enabled",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}
	
	
	Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			TextView textView = (TextView) findViewById(R.id.descriptionMap);
			//textView.setText(mRoad.mName + " " + mRoad.mDescription);
			mapController.animateTo(p);
			mapController.setZoom(17);
			
			MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
			List<Overlay> listOfOverlays = mapView.getOverlays();
			listOfOverlays.clear();
			listOfOverlays.add(mapOverlay);
			mapView.invalidate();
		};
	};

	private InputStream getConnection(String url) {
		InputStream is = null;
		try {
			URLConnection conn = new URL(url).openConnection();
			is = conn.getInputStream();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return is;
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
}

class MapOverlay extends com.google.android.maps.Overlay {
	Road mRoad;
	ArrayList<GeoPoint> mPoints;

	public MapOverlay(Road road, MapView mv) {
		mRoad = road;
		if (road.mRoute.length > 0) {
			mPoints = new ArrayList<GeoPoint>();
			for (int i = 0; i < road.mRoute.length; i++) {
				mPoints.add(new GeoPoint((int) (road.mRoute[i][1] * 1000000),
						(int) (road.mRoute[i][0] * 1000000)));
			}
			int moveToLat = (mPoints.get(0).getLatitudeE6() + (mPoints.get(
					mPoints.size() - 1).getLatitudeE6() - mPoints.get(0)
					.getLatitudeE6()) / 2);
			int moveToLong = (mPoints.get(0).getLongitudeE6() + (mPoints.get(
					mPoints.size() - 1).getLongitudeE6() - mPoints.get(0)
					.getLongitudeE6()) / 2);
			
			GeoPoint moveTo = new GeoPoint(moveToLat, moveToLong);
			MapController mapController=mv.getController();
			mapController.animateTo(moveTo);
			mapController.setZoom(10);
		}
	}

	@Override
	public boolean draw(Canvas canvas, MapView mv, boolean shadow, long when) {
		super.draw(canvas, mv, shadow);
		drawPath(mv, canvas);
		return true;
	}

	public void drawPath(MapView mv, Canvas canvas) {
		int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
		Paint paint = new Paint();
		paint.setColor(Color.RED);
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeWidth(5);
		for (int i = 0; i < mPoints.size(); i++) {
			Point point = new Point();
			mv.getProjection().toPixels(mPoints.get(i), point);
			x2 = point.x;
			y2 = point.y;
			if (i > 0) {
				canvas.drawLine(x1, y1, x2, y2, paint);
			}
			x1 = x2;
			y1 = y2;
		}
	}
}
